<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Tools\RecommenderSystem as RS;
use Cache;

class RecommenderSystem extends Command
{
    protected $signature = 'resys:train {--D|datadir= : where to save data, default is cache} {--K|chunk=1 : number of users chunk} {--U|vu=10 : number of voter} {--N|vn=10 : number of votes}';

    protected $description = 'recommender system';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle() : void
    {
        $k= intval($this->option("chunk"));
        $vu = intval($this->option("vu"));
        $vn = intval($this->option("vn"));
        $dir = $this->hasOption("datadir") ? $this->option("datadir") : null;
        $rs = new RS($k, $dir);
        // 1. 得到用户评分矩阵, O(n^2)
        $this->info("1. Compute user rating:");
        foreach ($rs->getRatingVectors() as $rv) {
            $bar1 = $bar1 ?? $this->output->createProgressBar($rv[1]);
            $bar1->setProgress($rv[0]);
        }
        $bar1->finish();
        $this->line("");

        // 2. 计算用户相似度矩阵, O(n^3)
        $this->info("2. Compute user similarity:");
        $bar2 = $this->output->createProgressBar($k);
        foreach ($rs->getSimilarityMatrix() as $sm) {
            $bar2->setProgress($sm[0]);
        }
        $bar2->finish();
        $this->line("");

        // 3. 投票决定为每一个用户推荐的产品, O(n)
        $this->info("3. vote:");
        $users = $rs->getMap()["users"];
        $bar3 = $this->output->createProgressBar(count($users));
        foreach ($users as $id) {
            $rs->vote($id, $vu, $vn);
            $bar3->advance();
        }
        $bar3->finish();
        $this->line("");

        // 4. 清除中间数据
        $this->info("4. clear cache:");
        foreach ($rs->clearCache() as $arr) {
            $bar4 = $bar4 ?? $this->output->createProgressBar($arr[1]);
            $bar4->setProgress($arr[0]);
        }
        $this->info("\nTrain done");

    }
}
